package com.kitty.game.drop.service;

import com.kitty.common.utils.SpringUtils;
import com.kitty.game.base.service.BagService;
import com.kitty.game.drop.DropDataPool;
import com.kitty.game.drop.model.product.DropSet;
import com.kitty.game.drop.model.product.FightDropSet;
import com.kitty.game.drop.model.product.ItemDropSet;
import com.kitty.game.drop.model.user.DropUnit;
import com.kitty.game.drop.newservice.NewDropService;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.utils.Const;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.concurrent.ThreadLocalRandom;
//后加
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
//import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Service
@Slf4j
public class DropService {
    @Autowired
    EquipService equipService;
    @Autowired
    RoleService roleService;
    @Autowired
    BagService bagService;
    @Autowired
    NewDropService newDropService;
    /**最大概率值，几分之一*/
    private final static int MAX_ODDS = 1000;
    /**不加入包裹 的*/
    private final static List<String> NOT_BAG = Arrays.asList(Const.EXP_NAME, Const.DAOHANG_NAME, Const.CHANGE_CARD_NAME, Const.PET_NAME, Const.POT_NAME);

    public void loadProduct() {
        loadDropSet();
        loadItemDropSet();
        //loadFightDropSet();
        loadFightDropBossSet();
    }

    /**加载掉落数据*/
    public void loadDropSet() {
        Dao dao = SpringUtils.getBean(Dao.class);
        List<DropSet> list = dao.query(DropSet.class, Cnd.NEW());
        Map<Integer, List<DropSet>> dropMapByGroup = new HashMap<>();
        for (DropSet dropSet : list) {
            List<DropSet> dropSets = dropMapByGroup.computeIfAbsent(dropSet.getDropGroup(), k -> new ArrayList<>());
            dropSets.add(dropSet);
        }

        DropDataPool.dropMapByGroup = dropMapByGroup;
    }

    /**加载物品对应掉落数据*/
    public void loadItemDropSet() {
        Dao dao = SpringUtils.getBean(Dao.class);
        List<ItemDropSet> list = dao.query(ItemDropSet.class, Cnd.NEW());
        Map<String, ItemDropSet> itemDropMap = new HashMap<>();
        for (ItemDropSet itemDropSet : list) {
            itemDropMap.put(itemDropSet.getItemName(), itemDropSet);
        }
        DropDataPool.itemDropMap = itemDropMap;
    }

    public void loadFightDropSet() {
//        Dao dao = SpringUtils.getBean(Dao.class);
//        List<FightDropSet> list = dao.query(FightDropSet.class, Cnd.NEW());
//        Map<Integer, FightDropSet> fightDropMap = new HashMap<>();
//
//        Map<Integer, List<FightDropSet>> fightType2DropMap = new HashMap<>();
//        for (FightDropSet fightDropSet : list) {
//            fightDropSet.getFightTypes().forEach((fightType) -> {
//                List<FightDropSet> fightDropSets = fightType2DropMap.computeIfAbsent(fightType, k -> new ArrayList<>());
//                fightDropSets.add(fightDropSet);
//            });
//
//        }
//        DropDataPool.fightType2DropMap = fightType2DropMap;
    }
    public void loadFightDropBossSet() {
        Dao dao = SpringUtils.getBean(Dao.class);
        List<FightDropSet> list = dao.query(FightDropSet.class, Cnd.NEW());
        Map<String, FightDropSet> fightDropMap = new HashMap<>();


        Map<String, List<FightDropSet>> loadFightDropBossSet = new HashMap<>();
        for (FightDropSet fightDropSet : list) {
            List<String> names = Arrays.asList(fightDropSet.getFightName().split(","));
            names.forEach((figthName) -> {
                List<FightDropSet> fightDropSets = loadFightDropBossSet.computeIfAbsent(figthName, k -> new ArrayList<>());
                fightDropSets.add(fightDropSet);
            });
        }
        DropDataPool.fightDropBossMap = loadFightDropBossSet;
    }

    /**从传入map中获得对应数据*/
    public void loadCommonSet(Map<String ,String> commonSetMap) {
        //TODO 暂时先这样读取，有需要时再加个表
        String dropLimitJson = commonSetMap.get("drop_limit");
        Map<String, Integer> map = Json.fromJson(Map.class, dropLimitJson);
        Map<Serializable, Integer> dropLimit = new HashMap<>();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            dropLimit.put(entry.getKey(), entry.getValue());
        }
        DropDataPool.dropLimit = dropLimit;
    }

    /**掉落*/
    public List<DropUnit> drop(Role role, int dropGroup) {
        return drop(role, dropGroup, null);
    }

    /**掉落*/
    public List<DropUnit> drop(Role role, int dropGroup, String dropLimitKey) {
        if (canDrop(role, dropLimitKey) == false) {
            return null;
        }
        List<DropUnit> dropList = doDrop(role, dropGroup);
        if (dropList == null || dropList.size() == 0) {
            return null;
        }
        /**判断下包裹空间是否足够，不足够时不添加掉落*/
        int posCount = getPosCount(dropList);
        if (posCount > 0 && SpringUtils.getBean(BagService.class).checkBagEnough(role, false, posCount) == false) {
            return null;
        }
        addDrop(role, dropList, dropLimitKey);
        return dropList;
    }

    /**判断是否可以掉落*/
    public boolean canDrop(Role role, String dropLimitKey) {
        Integer max = getMaxDropCount(role, dropLimitKey);
        /**不限制*/
        if (max == null) {return true;}

        /**判断已产生掉落的数量是否达到上限*/
        Map<String, Integer> dailyDropCountMap = role.getRoleDrop().getDailyDropCountMap();
        if (dailyDropCountMap == null || !dailyDropCountMap.containsKey(dropLimitKey)) {
            return true;
        }

        /**未达到上限*/
        if (dailyDropCountMap.get(dropLimitKey) < max) {
            return true;
        }

        return false;
    }

    /**获得剩余可掉落的数量， 返回-1表示没限制*/
    public int getRemainDropCount(Role role, String dropLimitKey) {
        Integer max = getMaxDropCount(role, dropLimitKey);
        /**不限制*/
        if (max == null) {return -1;}

        /**判断已产生掉落的数量是否达到上限*/
        Map<String, Integer> dailyDropCountMap = role.getRoleDrop().getDailyDropCountMap();
        if (dailyDropCountMap == null || !dailyDropCountMap.containsKey(dropLimitKey)) {
            return max;
        }

        if (dailyDropCountMap.get(dropLimitKey) < max) {
            return max - dailyDropCountMap.get(dropLimitKey);
        }

        return 0;
    }

    /**获得可掉落的上限*/
    public Integer getMaxDropCount(Role role, Serializable dropLimitKey) {
        return DropDataPool.dropLimit.get(dropLimitKey);
    }

    public List<DropSet> getDropSetList(int dropGroup) {
        return DropDataPool.dropMapByGroup.get(dropGroup);
    }

    private List<DropUnit> doDrop(Role role, int dropGroup) {
        List<DropUnit> dropList = new ArrayList<>();
        List<DropSet> dropSetList = getDropSetList(dropGroup);
        List<DropSet> list = new ArrayList<>();
        for (DropSet dropSet : dropSetList) {
            // 重写逻辑。  掉落类型统一 都经过概率计算。每个物品单独计算。
            ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
            int ran = threadLocalRandom.nextInt(MAX_ODDS);
            if (threadLocalRandom.nextInt(MAX_ODDS) < dropSet.getOdds()) {
                dropList.add(new DropUnit(dropSet, getDropCount(role.getLevel(), dropSet)));
            }

        }
        return dropList;
    }



    /**获得掉落数量*/
    private int getDropCount(short level, DropSet dropSet) {
        int count = 0;
        if (dropSet.getMinItemCount() == dropSet.getMaxItemCount()) {
            count = dropSet.getMaxItemCount();
        } else {
            count = ThreadLocalRandom.current().nextInt(dropSet.getMinItemCount(), dropSet.getMaxItemCount()+1);
        }
        if (dropSet.getMultiplyLevel() != 0) {
            count *= level;
        }
        return count;
    }

    public void addDrop(Role role, List<DropUnit> dropList, String dropLimitKey) {
        if (dropList == null) {return ;}

        for (DropUnit dropUnit : dropList) {
            addDrop(role, dropUnit, dropLimitKey);
        }
    }

    private boolean addDrop(Role role, DropUnit dropUnit, String dropLimitKey) {
        String limitKey = dropLimitKey != null ? dropLimitKey : dropUnit.getDropSet().getItemName();
        if (limitKey.equals("天倾石")){
            int value = new Random().nextInt(100);
            if (value >=10){
                return false;
            }
        }
        int count = dropUnit.getCount();
        if (isLimitDrop(role, limitKey)) {
            int remainCount = getRemainCount(role, limitKey);
            if (remainCount == 0) {return false;}

            count = dropUnit.getCount() > remainCount ? remainCount : dropUnit.getCount();
            addDropLimit(role, limitKey, count);
        }
        newDropService.addRewardTask(role,dropUnit.getDropSet().getExtraParam(),dropUnit.getDropSet().getNumor());
        //addItem(role, dropUnit, count,getNumorString(role,dropUnit.getDropSet(),dropUnit.getDropSet().getItemName()));

        return true;
    }

    public void addDropLimit(Role role, String dropLimitKey, int count) {
        Integer max = getMaxDropCount(role, dropLimitKey);
        /**不限制*/
        if (max == null) {return ;}

        Map<String, Integer> dailyDropCountMap = role.getRoleDrop().getDailyDropCountMap();
        if (dailyDropCountMap == null) {
            dailyDropCountMap = new HashMap<>();
            role.getRoleDrop().setDailyDropCountMap(dailyDropCountMap);
        }
        Integer hasCount = dailyDropCountMap.getOrDefault(dropLimitKey, 0);
        dailyDropCountMap.put(dropLimitKey, hasCount + count);

        role.save();
    }

    /**是否有限制 的掉落*/
    private boolean isLimitDrop(Role role, Serializable dropLimitKey) {
        return getMaxDropCount(role, dropLimitKey) != null;
    }

    /**获得剩余可加的数量*/
    private int getRemainCount(Role role, String dropLimitKey) {
        Integer max = getMaxDropCount(role, dropLimitKey);
        if (max == null) {
            return 0;
        }

        if (role.getRoleDrop().getDailyDropCountMap() == null) {
            return max;
        }

        return max - role.getRoleDrop().getDailyDropCountMap().getOrDefault(dropLimitKey, 0);
    }


    /**
     *

    *添加首饰
    private void addJewelry(Role role, DropUnit dropUnit, int count) {

        short pos = SpringUtils.getBean(BagService.class).getPos(role, false);
        if (pos <= 0) {
            return;
        }

        EquipService equipService = SpringUtils.getBean(EquipService.class);
        DropSet dropSet = dropUnit.getDropSet();
        List<String> nameList = (List<String>)dropSet.getExtraParam().get("name");
        String name = getRandomName(nameList);
        equipService.getJewelry(role, name, false, 1, true);

        String msg = MessageFormat.format("你获得了#R1{0}#n#R{1}#n。",  equipService.getItemUnit(name), name);
        MessagePusher.pushMessage(role, new RespNotifyMiscEx(msg));

        sendNumor(role, dropSet, name);
    }
     */
    /**重置掉落上限每日记录*/
    public void dailyReset(Role role) {
        if (role.getRoleDrop().getDailyDropCountMap() != null) {
            role.getRoleDrop().getDailyDropCountMap().clear();
        }
    }

    /**是否掉落物品(使用时产生掉落)*/
    public boolean isDropItem(String itemName) {
        return DropDataPool.fightDropBossMap.containsKey(itemName);
    }

    public List<FightDropSet> getItemDropSet(String itemName) {
        return DropDataPool.fightDropBossMap.get(itemName);
    }

    /**获得需要包裹格子数量*/
    public int getPosCount(List<DropUnit> dropList) {
        //TODO 没有判断加的数量是否超过叠加上限
        int count = 0;
        for (DropUnit dropUnit : dropList) {
            if (!NOT_BAG.contains(dropUnit.getDropSet().getItemName())) {
                count += 1;
            }
        }
        return count;
    }
}
